<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>简单 PlantUML 交互示例</title>
    <script src="https://unpkg.com/plantuml-encoder@1.4.0/dist/plantuml-encoder.min.js"></script>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
        }
        
        .container {
            max-width: 700px;
            margin: 0 auto;
            background: white;
            padding: 30px;
            border-radius: 15px;
            box-shadow: 0 8px 25px rgba(0,0,0,0.2);
        }
        
        h1 {
            text-align: center;
            color: #333;
            margin-bottom: 30px;
        }
        
        #diagram-container {
            position: relative;
            text-align: center;
            padding: 20px;
            background: #f8f9fa;
            border-radius: 10px;
            min-height: 250px;
        }
        
        .loading {
            color: #666;
            font-style: italic;
        }
        
        .popup-menu {
            position: absolute;
            background: white;
            border: 3px solid #28a745;
            border-radius: 10px;
            box-shadow: 0 6px 20px rgba(0,0,0,0.2);
            z-index: 1000;
            min-width: 140px;
            animation: slideIn 0.3s ease-out;
        }
        
        .popup-title {
            background: #28a745;
            color: white;
            padding: 10px 15px;
            font-weight: bold;
            font-size: 14px;
            border-radius: 7px 7px 0 0;
            text-align: center;
        }
        
        .popup-option {
            padding: 12px 15px;
            cursor: pointer;
            border-bottom: 1px solid #e9ecef;
            transition: all 0.2s;
            display: flex;
            align-items: center;
            gap: 8px;
        }
        
        .popup-option:hover {
            background: #f8f9fa;
            color: #28a745;
            transform: translateX(5px);
        }
        
        .popup-option:last-child {
            border-bottom: none;
            border-radius: 0 0 7px 7px;
        }
        
        @keyframes slideIn {
            from { 
                opacity: 0; 
                transform: translateY(-20px) scale(0.8); 
            }
            to { 
                opacity: 1; 
                transform: translateY(0) scale(1); 
            }
        }
        
        .node-glow {
            filter: drop-shadow(0 0 10px #ffc107);
        }
        
        .info-box {
            margin-top: 20px;
            padding: 15px;
            background: #d4edda;
            border: 1px solid #c3e6cb;
            border-radius: 5px;
            color: #155724;
        }
        
        .result-toast {
            position: fixed;
            top: 20px;
            right: 20px;
            background: #28a745;
            color: white;
            padding: 15px 20px;
            border-radius: 8px;
            box-shadow: 0 4px 15px rgba(0,0,0,0.2);
            z-index: 2000;
            animation: toastSlide 0.3s ease-out;
            max-width: 300px;
        }
        
        @keyframes toastSlide {
            from { transform: translateX(100%); }
            to { transform: translateX(0); }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>⚡ 简单 PlantUML 交互示例</h1>
        
        <div id="diagram-container">
            <div class="loading">正在加载图表...</div>
        </div>
        
        <div class="info-box">
            <strong>操作提示：</strong>点击图表中的任意组件查看可用操作
        </div>
    </div>

    <script>
        // 简单的 PlantUML 定义
        const plantUMLCode = `
            @startuml simple
            !theme blueprint
            
            component "Web应用" as web #lightblue
            database "数据库" as db #lightgreen
            
            web --> db : 查询数据
            
            note right of web : 前端界面
            note bottom of db : 存储层
            
            @enduml
        `;
        
        // 组件配置
        const componentConfig = {
            'Web应用': {
                name: 'Web应用',
                options: [
                    { text: '🔄 重启服务', icon: '🔄' },
                    { text: '📊 查看状态', icon: '📊' }
                ]
            },
            '数据库': {
                name: '数据库',
                options: [
                    { text: '🔍 检查连接', icon: '🔍' },
                    { text: '💾 备份数据', icon: '💾' }
                ]
            }
        };
        
        let nodeAreas = [];
        let currentPopup = null;
        
        // 初始化 PlantUML 图表
        async function initDiagram() {
            try {
                const encoded = plantumlEncoder.encode(plantUMLCode);
                const svgUrl = `https://www.plantuml.com/plantuml/svg/${encoded}`;
                
                const response = await fetch(svgUrl);
                const svgText = await response.text();
                
                const parser = new DOMParser();
                const svgDoc = parser.parseFromString(svgText, "image/svg+xml");
                const svgElement = svgDoc.documentElement;
                
                // 设置SVG样式
                svgElement.style.maxWidth = '100%';
                svgElement.style.height = 'auto';
                
                // 插入到容器
                const container = document.getElementById('diagram-container');
                container.innerHTML = '';
                container.appendChild(svgElement);
                
                // 分析结构并添加交互
                setTimeout(() => analyzeAndAddInteraction(svgElement, container), 300);
                
            } catch (error) {
                console.error('图表加载失败:', error);
                document.getElementById('diagram-container').innerHTML = 
                    '<div style="color: red;">图表加载失败，请检查网络连接</div>';
            }
        }
        
        // 分析SVG结构并添加交互
        function analyzeAndAddInteraction(svgElement, container) {
            nodeAreas = [];
            
            // 查找所有文本元素
            const textElements = svgElement.querySelectorAll('text');
            
            textElements.forEach(textEl => {
                const textContent = textEl.textContent.trim();
                const config = componentConfig[textContent];
                
                if (config) {
                    // 查找关联的图形元素
                    const graphic = findAssociatedGraphic(textEl);
                    
                    if (graphic) {
                        const bbox = graphic.getBBox();
                        
                        const nodeArea = {
                            name: textContent,
                            config: config,
                            element: graphic,
                            textElement: textEl,
                            bounds: {
                                x: bbox.x,
                                y: bbox.y,
                                width: bbox.width,
                                height: bbox.height
                            }
                        };
                        
                        nodeAreas.push(nodeArea);
                        
                        console.log(`找到组件: ${textContent}`, nodeArea);
                    }
                }
            });
            
            // 设置点击检测
            setupClickDetection(svgElement, container);
            
            console.log(`总共找到 ${nodeAreas.length} 个可交互组件`);
        }
        
        // 查找关联的图形元素
        function findAssociatedGraphic(textElement) {
            let parent = textElement.parentElement;
            
            while (parent && parent.tagName !== 'svg') {
                const graphic = parent.querySelector('rect, ellipse, polygon, path[d*="M"]');
                if (graphic && graphic !== textElement) {
                    return graphic;
                }
                parent = parent.parentElement;
            }
            
            return null;
        }
        
        // 设置点击检测
        function setupClickDetection(svgElement, container) {
            svgElement.addEventListener('click', (event) => {
                const clickedNode = detectClickedNode(event, svgElement);
                
                if (clickedNode) {
                    handleNodeClick(event, clickedNode, container);
                } else {
                    hidePopup();
                }
            });
        }
        
        // 检测点击的节点
        function detectClickedNode(event, svgElement) {
            const rect = svgElement.getBoundingClientRect();
            const x = event.clientX - rect.left;
            const y = event.clientY - rect.top;
            
            for (let nodeArea of nodeAreas) {
                const bounds = nodeArea.bounds;
                
                if (x >= bounds.x && x <= bounds.x + bounds.width &&
                    y >= bounds.y && y <= bounds.y + bounds.height) {
                    return nodeArea;
                }
            }
            return null;
        }
        
        // 处理节点点击
        function handleNodeClick(event, nodeArea, container) {
            console.log('点击了组件:', nodeArea.name);
            
            // 高亮节点
            highlightNode(nodeArea.element);
            
            // 显示弹出菜单
            showPopupMenu(event, nodeArea, container);
        }
        
        // 高亮节点
        function highlightNode(element) {
            // 清除所有高亮
            nodeAreas.forEach(area => {
                area.element.classList.remove('node-glow');
            });
            
            // 高亮当前节点
            element.classList.add('node-glow');
        }
        
        // 显示弹出菜单
        function showPopupMenu(event, nodeArea, container) {
            hidePopup();
            
            const containerRect = container.getBoundingClientRect();
            const nodeRect = nodeArea.element.getBoundingClientRect();
            
            // 创建弹出菜单
            const popup = document.createElement('div');
            popup.className = 'popup-menu';
            
            // 计算位置
            const left = nodeRect.right - containerRect.left + 15;
            const top = nodeRect.top - containerRect.top;
            
            popup.style.left = left + 'px';
            popup.style.top = top + 'px';
            
            // 添加标题
            const title = document.createElement('div');
            title.className = 'popup-title';
            title.textContent = nodeArea.config.name;
            popup.appendChild(title);
            
            // 添加选项
            nodeArea.config.options.forEach(option => {
                const item = document.createElement('div');
                item.className = 'popup-option';
                item.innerHTML = `<span>${option.icon}</span><span>${option.text.replace(option.icon + ' ', '')}</span>`;
                
                item.addEventListener('click', () => {
                    executeAction(nodeArea.name, option.text);
                    hidePopup();
                });
                
                popup.appendChild(item);
            });
            
            container.appendChild(popup);
            currentPopup = popup;
            
            // 4秒后自动关闭
            setTimeout(hidePopup, 4000);
        }
        
        // 执行操作
        function executeAction(componentName, action) {
            console.log(`执行操作: ${componentName} -> ${action}`);
            
            const results = {
                '🔄 重启服务': `${componentName} 重启完成\n✅ 服务已成功重启\n⏱️ 耗时: 2.3秒`,
                '📊 查看状态': `${componentName} 状态报告\n✅ 运行正常\n💾 内存使用: 45%\n🔥 CPU使用: 23%`,
                '🔍 检查连接': `${componentName} 连接检查\n✅ 连接正常\n📡 延迟: 3ms\n🔗 连接数: 12/50`,
                '💾 备份数据': `${componentName} 数据备份\n✅ 备份完成\n📁 文件大小: 2.1GB\n⏰ 备份时间: ${new Date().toLocaleTimeString()}`
            };
            
            const result = results[action] || `${action} 执行完成`;
            showToast(result);
        }
        
        // 显示Toast通知
        function showToast(message) {
            const toast = document.createElement('div');
            toast.className = 'result-toast';
            toast.innerHTML = message.replace(/\n/g, '<br>');
            
            document.body.appendChild(toast);
            
            setTimeout(() => {
                if (toast.parentNode) {
                    toast.style.animation = 'toastSlide 0.3s ease-in reverse';
                    setTimeout(() => {
                        if (toast.parentNode) {
                            toast.parentNode.removeChild(toast);
                        }
                    }, 300);
                }
            }, 3000);
        }
        
        // 隐藏弹出菜单
        function hidePopup() {
            if (currentPopup) {
                currentPopup.remove();
                currentPopup = null;
            }
            
            // 清除高亮
            nodeAreas.forEach(area => {
                area.element.classList.remove('node-glow');
            });
        }
        
        // 点击空白区域关闭
        document.addEventListener('click', (event) => {
            if (!event.target.closest('.popup-menu') && 
                !event.target.closest('#diagram-container svg')) {
                hidePopup();
            }
        });
        
        // 键盘ESC关闭
        document.addEventListener('keydown', (event) => {
            if (event.key === 'Escape') {
                hidePopup();
            }
        });
        
        // 初始化
        initDiagram();
    </script>
</body>
</html>